<template>
  <!-- html 结构 -->
  <div class="person">
    <h1>情况三：监视【reactive】定义的【对象类型】类数据</h1>
    <h2>姓名：{{ person.name }}</h2>
    <h2>年龄：{{ person.age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changePerson">修改整个人</button>
  </div>
</template>

<!-- 在vue3中监事一个reactive定义的响应式常量应该是这么写的 -->
<script lang="ts" setup name="Person">
/**  总结一下watch能监听的4总类型：
 * 1、ref修饰的基本类型和对象类型
 * 2、reactive修饰的对象类型
 * 3、一个函数，返回一个值
 * 4、由以上类型组成的数组
 */
import { reactive, watch } from "vue";

let person = reactive({
  name: "张三",
  age: 18,
});

function changeName() {
  person.name += "~";
}
function changeAge() {
  person.age += 1;
}
function changePerson() {
  // person.name = '李四'
  // person.age = 19

  // reactive 修饰的对象不能使用下面的方式重新定义
  // person = {
  //   name: "张三",
  //   age: 18,
  // };
  // person = reactive({
  //   name: "张三",
  //   age: 18,
  // });

  // 需要使用这个注释下面的方式重新定义对象，但是只是修改了对象的内部属性，并不会是一个全新的对象即对象地址不变
  Object.assign(person, { name: "李四", age: 30 });
}

// reactive修饰的对象是默认开启深度监听的
/**
 * watch的第一个参数是：被监听的数据
 * watch的第二个参数是：监视器的回调
 * watch的第三个参数是：配置对象（deep:开启深度监听，immediate:页面加载即刻监听一次）
 */
watch(
  person,
  (newVal, oldVal) => {
    console.log("person变化了newVal=", newVal, ", oldVal=", oldVal);
  }
);
</script>

<!-- 在vue2中监事一个ref定义的响应式常量应该是这么写的 -->
<!-- <script lang="ts">
export default {
  name: "Plugin-name",
  data() {
    return {
      sum: 0,
    };
  },
  methods: {
    addSum() {
      this.sum += 1;
    },
  },
  watch: {
    sum(newVal, oldVal) {
      console.log("sum 变化:", newVal, oldVal);
    },
  },
};
</script> -->

<style>
/* 样式 */
button {
  background-color: aqua;
  margin: 5px;
}
</style>
